﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web;

namespace GSite.Utils.Unity
{
    /// <summary>
    /// <see cref="System.Web.Mvc.DefaultControllerFactory"/>
    /// </summary>
    public class UnityControllerFactory : DefaultControllerFactory
    {
        private IUnityContainer _unityContainer;

        /// <summary>
        /// Конструктор на класа
        /// </summary>
        /// <param name="unityContainer">Референция към Unity container</param>
        public UnityControllerFactory(IUnityContainer unityContainer)
        {
            _unityContainer = unityContainer;
        }

        /// <summary>
        /// <see cref="System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(System.Web.Routing.RequestContext, System.Type)"/>
        /// </summary>
        /// <param name="requestContext"></param>
        /// <param name="controllerType"></param>
        /// <returns></returns>
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (controllerType == null)
            {
                //return null;
                throw new HttpException(404,
                    String.Format(
                        "The controller for path '{0}' was not found or does not implement IController.",
                        requestContext.HttpContext.Request.Path));
            }
            if (!typeof(IController).IsAssignableFrom(controllerType))
            {
                throw new ArgumentException(
                    String.Format(
                        "The controller type '{0}' must implement IController.",
                        controllerType),
                    "controllerType");
            }
            try
            {
                return (IController)_unityContainer.Resolve(controllerType);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(
                    String.Format(
                        "An error occurred when trying to create a controller of type '{0}'. Make sure that the controller has a parameterless public constructor.",
                        controllerType),
                    ex);
            }
        }

        public override void ReleaseController(IController controller)
        {
            _unityContainer.Teardown(controller);

            base.ReleaseController(controller);
        }
    }
}
